/*
 * CAllStats.java
 * 
 * Copyright (c) 2009 Giles Millward (Manigra). All rights reserved.
 * 
 * This file is part of JRogueDPS.
 * 
 * JRogueDPS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * JRogueDPS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with JRogueDPS.  If not, see <http://www.gnu.org/licenses/>.
 */

package dpsstats;

import java.util.ArrayList;

/**
 *
 * @author Giles Millward (Manigra)
 */
public class CAllStats {
    // Physical auto attack damage (not poisons)
    public CDamageStats m_MHAutoAttack = new CDamageStats("MH Auto Attack");
    public CDamageStats m_OHAutoAttack = new CDamageStats("OH Auto Attack");

    // Poison stats
    public CDamageStats m_MHPoisonStats = new CDamageStats();
    public CDamageStats m_OHPoisonStats = new CDamageStats();

    // Combo point builder stats
    public CDamageStats m_mutilateStats = new CDamageStats("Mutilate");
    public CDamageStats m_sinisterStrikeStats = new CDamageStats("Sinister Strike");
    public CDamageStats m_backStabStats = new CDamageStats("Back Stab");

    // Finishers
    public CDamageStats m_envenomStats = new CDamageStats("Envenom");
    public CDamageStats m_eviscerateStats = new CDamageStats("Eviscerate");
    public CDamageStats m_ruptureStats = new CDamageStats("Rupture App"); // Application of rupture only
    public CDamageStats m_sliceAndDiceStats = new CDamageStats("Slice and Dice App");

    // DOT stats
    public CDamageStats m_ruptureDOTStats = new CDamageStats("Rupture DOT");
    public CDamageStats m_deadlyPoisonDOTStats = new CDamageStats("Deadly Poison DOT");
    public CDamageStats m_garroteDOTStats = new CDamageStats("Garrote DOT");

    // Deadly Poison stack stats
    public CDeadlyPoisonStats m_deadlyPoisonStackStats = new CDeadlyPoisonStats();

    // Proc stats
    public ArrayList<CProcStats> m_procStats = new ArrayList<CProcStats>();

    // CEnergyStats
    public ArrayList<CEnergyStats> m_energyStats = new ArrayList<CEnergyStats>();

    // Finisher stats that store combo point usage
    public ArrayList<CFinisherStats> m_finisherStatsList = new ArrayList<CFinisherStats>();

    // Some potentially useful arrays
    public ArrayList<CDamageStats> m_allStats = new ArrayList<CDamageStats>();
    public ArrayList<CDamageStats> m_poisonStats = new ArrayList<CDamageStats>();
    public ArrayList<CDamageStats> m_autoAttackStats = new ArrayList<CDamageStats>();
    public ArrayList<CDamageStats> m_finisherStats = new ArrayList<CDamageStats>();
    public ArrayList<CDamageStats> m_dotStats = new ArrayList<CDamageStats>();
    public ArrayList<CDamageStats> m_comboPointBuilderStats = new ArrayList<CDamageStats>();

    public double m_runTime;
    public double m_totalDPS;
    public double m_standardDeviation;
    public double m_totalDamage = 0.0;
    public ArrayList<Double> m_iterationDPS = new ArrayList<Double>();
    
    public CAllStats(double p_runTime)
    {
        m_runTime = p_runTime;
        initStats();
    }

    public CAllStats(CAllStats p_allStats)
    {
        initStats();
        m_runTime = p_allStats.m_runTime;

        for (int i = 0; i < p_allStats.m_procStats.size(); i++)
        {
            this.m_procStats.add(new CProcStats(p_allStats.m_procStats.get(i).m_name));
        }
    }

    private void initStats()
    {
        m_allStats.add(m_MHAutoAttack);
        m_allStats.add(m_OHAutoAttack);

        m_allStats.add(m_MHPoisonStats);
        m_allStats.add(m_OHPoisonStats);

        m_allStats.add(m_mutilateStats);
        m_allStats.add(m_sinisterStrikeStats);
        m_allStats.add(m_backStabStats);

        m_allStats.add(m_envenomStats);
        m_allStats.add(m_eviscerateStats);
        m_allStats.add(m_ruptureStats);
        m_allStats.add(m_sliceAndDiceStats);

        m_allStats.add(m_ruptureDOTStats);
        m_allStats.add(m_deadlyPoisonDOTStats);
        m_allStats.add(m_garroteDOTStats);

        m_poisonStats.add(m_MHPoisonStats);
        m_poisonStats.add(m_OHPoisonStats);

        m_autoAttackStats.add(m_MHAutoAttack);
        m_autoAttackStats.add(m_OHAutoAttack);

        m_comboPointBuilderStats.add(m_mutilateStats);
        m_comboPointBuilderStats.add(m_sinisterStrikeStats);
        m_comboPointBuilderStats.add(m_backStabStats);

        m_finisherStats.add(m_envenomStats);
        m_finisherStats.add(m_eviscerateStats);
        m_finisherStats.add(m_ruptureStats);
        m_finisherStats.add(m_sliceAndDiceStats);

        m_dotStats.add(m_ruptureDOTStats);
        m_dotStats.add(m_deadlyPoisonDOTStats);
        m_dotStats.add(m_garroteDOTStats);

        // Energy Regen stats
        this.m_energyStats.add(new CEnergyStats("Auto Regen"));
        this.m_energyStats.add(new CEnergyStats("Capped Energy"));
        this.m_energyStats.add(new CEnergyStats("Focused Attacks"));
        this.m_energyStats.add(new CEnergyStats("Relentless Strikes"));
        this.m_energyStats.add(new CEnergyStats("Combat Potency"));
        this.m_energyStats.add(new CEnergyStats("Tier8 2 Piece Bonus"));

        // Finisher stats
        this.m_finisherStatsList.add(new CFinisherStats("Envenom"));
        this.m_finisherStatsList.add(new CFinisherStats("Eviscerate"));
        this.m_finisherStatsList.add(new CFinisherStats("Slice And Dice"));
        this.m_finisherStatsList.add(new CFinisherStats("Rupture"));
    }

    public void add(CAllStats p_allStats)
    {
        m_MHAutoAttack.add(p_allStats.m_MHAutoAttack);
        m_OHAutoAttack.add(p_allStats.m_OHAutoAttack);

        m_MHPoisonStats.add(p_allStats.m_MHPoisonStats);
        m_OHPoisonStats.add(p_allStats.m_OHPoisonStats);

        m_mutilateStats.add(p_allStats.m_mutilateStats);
        m_sinisterStrikeStats.add(p_allStats.m_sinisterStrikeStats);
        m_backStabStats.add(p_allStats.m_backStabStats);

        m_envenomStats.add(p_allStats.m_envenomStats);
        m_eviscerateStats.add(p_allStats.m_eviscerateStats);
        m_ruptureStats.add(p_allStats.m_ruptureStats);
        m_sliceAndDiceStats.add(p_allStats.m_sliceAndDiceStats);

        m_ruptureDOTStats.add(p_allStats.m_ruptureDOTStats);
        m_deadlyPoisonDOTStats.add(p_allStats.m_deadlyPoisonDOTStats);
        m_garroteDOTStats.add(p_allStats.m_garroteDOTStats);

        m_deadlyPoisonStackStats.add(p_allStats.m_deadlyPoisonStackStats);

        for (int i = 0; i < this.m_procStats.size(); i++)
        {
            m_procStats.get(i).add(p_allStats.m_procStats.get(i));
        }

        for (int i = 0; i < this.m_energyStats.size(); i++)
        {
            m_energyStats.get(i).add(p_allStats.m_energyStats.get(i));
        }

        for (int i = 0; i < this.m_finisherStatsList.size(); i++)
        {
            m_finisherStatsList.get(i).add(p_allStats.m_finisherStatsList.get(i));
        }
    }

    public void divideBy(int p_iterations)
    {
        for (int i = 0; i < m_allStats.size(); i ++)
        {
            m_allStats.get(i).divideBy(p_iterations);
        }

        m_deadlyPoisonStackStats.divideBy(p_iterations);

        for (int i = 0; i < this.m_procStats.size(); i++)
        {
            m_procStats.get(i).divideBy(p_iterations);
        }

        for (int i = 0; i < this.m_energyStats.size(); i++)
        {
            m_energyStats.get(i).divideBy(p_iterations);
        }

        for (int i = 0; i < this.m_finisherStatsList.size(); i++)
        {
            m_finisherStatsList.get(i).divideBy(p_iterations);
        }
    }

    public void calculateTotalDPS()
    {
        m_totalDamage = getTotalDamage(m_allStats);
        m_totalDPS = (m_totalDamage / m_runTime);
    }
        
    public double getTotalDPS()
    {
        return m_totalDPS;
    }

    public double getStandardDeviation()
    {
        return m_standardDeviation;
    }

    public double getTotalDamage(ArrayList<CDamageStats> p_stats)
    {
        double l_totalDamage = 0;
        for (int i = 0; i < p_stats.size(); i++)
        {
            l_totalDamage += p_stats.get(i).getTotalDamage();
        }

        return l_totalDamage;
    }

    public double getTotalPoison(String p_poison)
    {
        double l_totalDamage = 0.0;
        if (p_poison.contains("Deadly"))
        {
            l_totalDamage += this.m_deadlyPoisonDOTStats.getTotalDamage();
        }
        else if (this.m_MHPoisonStats.getName().contains(p_poison))
        {
            l_totalDamage += this.m_MHPoisonStats.getTotalDamage();
        } else if (this.m_OHPoisonStats.getName().contains(p_poison))
        {
            l_totalDamage += this.m_MHPoisonStats.getTotalDamage();
        } 

        return l_totalDamage;
    }

    public CDamageStats getTotalStats(String p_name, ArrayList<CDamageStats> p_stats)
    {
        CDamageStats l_newStats = new CDamageStats();
        for (int i = 0; i < p_stats.size(); i++)
        {
            l_newStats.add(p_stats.get(i));
        }

        l_newStats.setName(p_name);
        return l_newStats;
    }
}
